{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Weather map"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook shows an example of use of the `AppLayout` template, which is documented in [Layout Templates](Layout%20Templates.ipynb) notebook. You can check that notebook for further explanation.\n",
    "\n",
    "This notebook depends on extra packages:\n",
    "\n",
    "* [bqplot](https://github.com/bloomberg/bqplot) - widget-based plotting library,\n",
    "* [ipyleaflet](https://github.com/jupyter-widgets/ipyleaflet) - cartography widget based on leaflet.js \n",
    "\n",
    "If you also would like to see a color weather map, you will need to obtain an API key from [OpenWeahterMap](https://openweathermap.org/)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from ipyleaflet import Map, basemaps, basemap_to_tiles, Heatmap, TileLayer\n",
    "from ipywidgets import AppLayout\n",
    "from ipywidgets import HTML, Layout, Dropdown, Output, Textarea, VBox, Label\n",
    "import bqplot as bq\n",
    "import numpy as np\n",
    "from pandas import date_range"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To see map overlays obtain your API key free of charge from [OpenWeatherMap](https://openweathermap.org/) and paste it below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "OWM_API_KEY = \"PASTE_YOUR_OWM_API_KEY_HERE\" #openweathermap API key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m = Map(center=(52, 10), zoom=5, basemap=basemaps.Hydda.Full)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "maps = {'Hydda' : basemaps.Hydda.Full,\n",
    "        'Esri' : basemaps.Esri.DeLorme}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "header = HTML(\"<h1>Fictional World Weather</h1>\", layout=Layout(height='auto'))\n",
    "header.style.text_align='center'\n",
    "basemap_selector = Dropdown( options = list(maps.keys()),\n",
    "                            layout=Layout(width='auto'))\n",
    "\n",
    "heatmap_selector = Dropdown(options=('Temperature', 'Precipitation'),\n",
    "                            layout=Layout(width='auto'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "basemap_selector.value = 'Hydda'\n",
    "m.layout.height='600px'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "security_1 = np.cumsum(np.random.randn(150)) + 100.\n",
    "\n",
    "dates = date_range(start='01-01-2007', periods=150)\n",
    "\n",
    "dt_x = bq.DateScale()\n",
    "sc_y = bq.LinearScale()\n",
    "\n",
    "time_series = bq.Lines(x=dates, y=security_1, scales={'x': dt_x, 'y': sc_y})\n",
    "ax_x = bq.Axis(scale=dt_x)\n",
    "ax_y = bq.Axis(scale=sc_y, orientation='vertical')\n",
    "\n",
    "fig = bq.Figure(marks=[time_series], axes=[ax_x, ax_y],\n",
    "                fig_margin=dict(top=0, bottom=80, left=30, right=20))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.layout.width='auto'\n",
    "m.layout.height='auto'\n",
    "fig.layout.width='auto'\n",
    "fig.layout.height='auto'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "out = HTML(\n",
    "    value='',\n",
    "    layout=Layout(width='auto', height='auto')\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "AppLayout(center=m, \n",
    "          header=header,\n",
    "          left_sidebar=VBox([Label(\"Basemap:\"),\n",
    "                             basemap_selector,\n",
    "                             Label(\"Overlay:\"),\n",
    "                             heatmap_selector]),\n",
    "          right_sidebar=fig,\n",
    "          footer=out,\n",
    "          pane_widths=['80px', 1, 1],\n",
    "          pane_heights=['80px', 4, 1],\n",
    "          height='600px',\n",
    "          grid_gap=\"30px\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "rows = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X, Y = np.mgrid[-90:90:10j, -180:180:20j]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = X.flatten()\n",
    "Y = Y.flatten()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "temps = np.random.randn(200, 150)*0.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def add_log(msg):\n",
    "    max_rows = 3\n",
    "    rows.append(msg)\n",
    "    if len(rows) > max_rows:\n",
    "        rows.pop(0)\n",
    "    return '<h4>Activity log</h4><ul>{}</ul>'.format('<li>'.join([''] + rows))\n",
    "\n",
    "def generate_temp_series(x, y):\n",
    "    if heatmap_selector.value == 'Precipitation':\n",
    "        temp = np.cumsum(np.random.randn(150)) + 100.\n",
    "    elif heatmap_selector.value == 'Temperature':\n",
    "        dist = np.sqrt((X - x)**2 + (Y-y)**2) / 100\n",
    "        dist = dist.max() - dist\n",
    "        dist[dist > np.percentile(dist, 5)] = 0\n",
    "        temp = np.cumsum(np.dot(dist, temps)+0.05) + 20 - np.abs(x) / 2\n",
    "    time_series.y = temp\n",
    "    \n",
    "def handle_interaction(**kwargs):\n",
    "    if kwargs['type'] == 'click':\n",
    "        generate_temp_series(*kwargs['coordinates'])\n",
    "        msg = '%s Selected coordinates: %s, Temp: %d C Precipitation: %d mm\\n' % (\n",
    "            datetime.now(), kwargs['coordinates'], random.randint(-20, 20), random.randint(0, 100))\n",
    "        out.value = add_log(msg)\n",
    "\n",
    "m.on_interaction(handle_interaction) \n",
    "\n",
    "def on_map_selected(change):\n",
    "    m.layers = [basemap_to_tiles(maps[basemap_selector.value]), weather_maps[heatmap_selector.value]]\n",
    "    \n",
    "basemap_selector.observe(on_map_selected, names='value')\n",
    "heatmap_selector.observe(on_map_selected, names='value')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "temp = TileLayer(min_zoom=1, max_zoom=18, url='https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid='+OWM_API_KEY, name='owm', attribute='me')\n",
    "precipitation = TileLayer(min_zoom=1, max_zoom=18, url='https://tile.openweathermap.org/map/precipitation_new/{z}/{x}/{y}.png?appid='+OWM_API_KEY, name='owm', attribute='me')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "weather_maps = {'Temperature' : temp,\n",
    "                'Precipitation' : precipitation}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "m.add_layer(weather_maps[heatmap_selector.value])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  },
  "nbsphinx": {
   "execute": "never",
   "orphan": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
